/*
 * DatagramBuilder Library: serialize/deserialize data to/from datagram
 * Copyright (C) 2008 Rakov Ilya <RakovIlya@gmail.com>
 *
 * This library can be distributed under the terms of the GNU LGPLv2.
 * See the file COPYING.LIB.
 */


/**
 * @file BuilderImpl.h
 *
 * @brief Builder implementation file
 *
 * @date Dec 2, 2008
 * @author Rakov Ilya
 */


template< class T >
struct SerializeImpl;


class Builder::ScopedTransaction
{

public:

  ScopedTransaction( Builder& builder )
  : transaction_( builder.container_ )
  {
  }

private:

  Container::ScopedTransaction transaction_;

};


Parser Builder::GetParser() const
{
  return Parser( container_ );
}


size_t Builder::GetSize() const
{
  return container_.GetSize();
}


template< class T >
void Builder::SerializeValue( const T value )
{
  return container_.SerializeValue( value );
}


template< class SIZE_T >
void Builder::SerializeValue( cpointer_t bgn, cpointer_t end )
{
  return container_.SerializeValue<SIZE_T>( bgn, end );
}


template< class T >
void Builder::SerializeValue( const T value, size_t offset )
{
  return container_.SerializeValue( value, offset );
}


template< class CharType, class CharTrait >
void Builder::ToStream( std::basic_ostream< CharType, CharTrait > &out ) const
{
  out << container_;
}


template < class T >
Builder& Builder::operator <<( const T &value )
{
  ScopedTransaction transaction( *this );

  SerializeImpl< const T >::Serialize( *this, value );

  return *this;
}


template < class T >
Builder& Builder::operator <<( T &value )
{
  ScopedTransaction transaction( *this );

  SerializeImpl< T >::Serialize( *this, value );

  return *this;
}


template < class T >
Builder& Builder::operator <<( Tag< T > value )
{
  ScopedTransaction transaction( *this );

  SerializeImpl< T >::SerializeTag( *this );
  SerializeImpl< T >::Serialize( *this, value.value_ );

  return *this;
}


template< class CharType, class CharTrait >
std::basic_ostream< CharType, CharTrait >&
operator <<( std::basic_ostream<CharType, CharTrait> &out, const Builder &obj )
{
  obj.ToStream( out );

  return out;
}
